#include <stdio.h>
#include <stdbool.h>
#define SIZE 10

//五子棋

void InitBoard(char (*Board)[SIZE])
{
    for(int i=0;i<SIZE;i++)
    {
        for(int j=0;j<SIZE;j++)
        {
            Board[i][j]='-';
        }
    }
}

void PrintBoard(char (*Board)[SIZE])
{
    printf("  ");
    for(int i=0;i<SIZE;i++)
    {
        printf("  %d",i+1);
    }
    printf("\n");

    for(int i=0;i<SIZE;i++)
    {
        printf("%2d",i+1);
        for(int j=0;j<SIZE;j++)
        {
            printf("  %c",Board[i][j]);
        }
        printf("\n");
    }
}

bool MakeMove(char (*Board)[SIZE],int row,int col,char player)
{
    if(row<0 || row>=SIZE ||col<0 || col>=SIZE)
    {
        printf("非法位置!请重新输入!\n");
        return false;
    }

    if(Board[row][col]!='-')
    {
        printf("位置非空！请重新输入");
        return false;
    }

    Board[row][col]=player;
    return true;
}

bool CheckIsDrawn(char (*Board)[SIZE])
{
    for(int i=0;i<SIZE;i++)
    {
        for(int j=0;j<SIZE;j++)
        {
            if(Board[i][j]=='-')
            {
                return false;
            }
        }
    }
    return true;
}


bool IsValidPlace(int row,int col)
{
    if(row<0 || row>=SIZE ||col<0 || col>=SIZE)
    {
        return false;
    }
    return true;
}

bool CheckIsWin(char (*Board)[SIZE],char player,int row,int col)
{
    //向量数组
    int direction[4][2]=
    {
        {1,0},
        {1,1},
        {0,1},
        {-1,1}
    };
    //遍历4个方向,出现五个棋子则获胜
    for(int i=0;i<4;i++)
    {
        int count=1;
        //下一个棋子得位置
        int drow=row+direction[i][0];
        int dcol=col+direction[i][1];
        while(IsValidPlace(drow,dcol)
            &&Board[drow][dcol]==player)
             {
                count++;
                if(count==5)
                {
                    return true;
                }
                drow=drow+direction[i][0];
                dcol=dcol+direction[i][1];
             }
             //反方向继续找
             drow=row-direction[i][0];
             dcol=col-direction[i][1];
             while(IsValidPlace(drow,dcol)
            &&Board[drow][dcol]==player
             )
             {
                count++;
                if(count==5)
                {
                    return true;
                }
                drow=drow-direction[i][0];
                dcol=dcol-direction[i][1];
             }
    }
    return false;
}


bool CheckIsCount(char (*Board)[SIZE],char player,int row,int col,int number)
{
    //向量数组
    int direction[4][2]=
    {
        {1,0},
        {1,1},
        {0,1},
        {-1,1}
    };
    //遍历4个方向,出现五个棋子则获胜
    for(int i=0;i<4;i++)
    {
        int count=1;
        //下一个棋子得位置
        int drow=row+direction[i][0];
        int dcol=col+direction[i][1];
        while(IsValidPlace(drow,dcol)
            &&Board[drow][dcol]==player)
             {
                count++;
                if(count==number)
                {
                    return true;
                }
                drow=drow+direction[i][0];
                dcol=dcol+direction[i][1];
             }
             //反方向继续找
             drow=row-direction[i][0];
             dcol=col-direction[i][1];
             while(IsValidPlace(drow,dcol)
            &&Board[drow][dcol]==player
             )
             {
                count++;
                if(count==number)
                {
                    return true;
                }
                drow=drow-direction[i][0];
                dcol=dcol-direction[i][1];
             }
    }
    return false;
}


bool AiMakeMove(char (*Board)[SIZE],int playerrow,int playercol,char player,char AI)
{
    //智能决策 策略
    //优先取胜策略
    for(int i=0;i<SIZE;i++)
    {
        for(int j=0;j<SIZE;j++)
        {
            if(Board[i][j]=='-')
            {
                Board[i][j]=AI;
                if(CheckIsWin(Board,i,j,AI)==true)
                {
                    return true;
                }
                Board[i][j]='-';
            }
        }
    }
    //阻止对手策略
    for(int i=0;i<SIZE;i++)
    {
        for(int j=0;j<SIZE;j++)
        {
            if(Board[i][j]=='-')
            {
                Board[i][j]=player;
                if(CheckIsWin(Board,i,j,player)==true)
                {
                    Board[i][j]=AI;
                    return false;
                }
                Board[i][j]='-';
            }
        }
    }
    // 阻止对手连四个
    for(int i=0;i<SIZE;i++)
    {
        for(int j=0;j<SIZE;j++)
        {
            if(Board[i][j]=='-')
            {
                Board[i][j]=player;
                if(CheckIsCount(Board,i,j,player,4)==true)
                {
                    Board[i][j]=AI;
                    return false;
                }
                Board[i][j]='-';
            }
        }
    }
//阻止连三个
    for(int i=0;i<SIZE;i++)
    {
        for(int j=0;j<SIZE;j++)
        {
            if(Board[i][j]=='-')
            {
                Board[i][j]=player;
                if(CheckIsCount(Board,i,j,player,3)==true)
                {
                    Board[i][j]=AI;
                    return false;
                }
                Board[i][j]='-';
            }
        }
    }
    //阻止连两个
    for(int i=0;i<SIZE;i++)
    {
        for(int j=0;j<SIZE;j++)
        {
            if(Board[i][j]=='-')
            {
                Board[i][j]=player;
                if(CheckIsCount(Board,i,j,player,2)==true)
                {
                    Board[i][j]=AI;
                    return false;
                }
                Board[i][j]='-';
            }
        }
    }

    //随机策略
    // int direction[8][2]={0};
    // int count=0;
    // for(int i=0;i<4;i++)
    // {

    // }


}

int main()
{
    char Board[SIZE][SIZE]={0};

    InitBoard(Board);

    char player = 'x';
    int row,col;
    while(1)
    {
        PrintBoard(Board);
      
        if(player=='x')
        {
            printf("请|%c|选手下棋",player);
            scanf("%d %d",&row,&col);
            if(MakeMove(Board,row-1,col-1,player)==false)
            {
                continue;
            }
        }
        else
        {
            printf("AI正在下棋...\n");
            if(AiMakeMove(Board,row-1,col-1,'x','o')==true)
            {
                printf("AI获胜\n");
                break;
            }
        }
        

        if(CheckIsWin(Board,player,row-1,col-1)==true)
        {
            PrintBoard(Board);
            printf("恭喜选手|%c|获胜\n",player);
            break;
        }

        if(CheckIsDrawn(Board)==true)
        {
            PrintBoard(Board);
            printf("平局\n");
            break;
        }

        player=(player=='x')? 'o':'x';


    }

    return 0;
}